package ws_server

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"

	"github.com/gorilla/websocket"
)

type Msg struct {
	Uid string `json:"uid"`
	Msg string `json:"msg"`
}

var chMsg = make(chan *Msg, 10)
var upgrade = websocket.Upgrader{}

var clients = make(map[*websocket.Conn]int)
var clientMsg = make(map[*websocket.Conn]int)

var root string

func init() {
	if dir, err := os.Getwd(); err != nil {
		panic(err)
	} else {
		root = dir
	}
	go getMsg()
	go sendMsg()
}

func sendMsg() {
	for {
		msg := <-chMsg
		if msg != nil {
			fmt.Println("sending msg:", msg.Uid, msg.Msg)
			msgByte, _ := json.Marshal(msg)
			// 发送给所有客户端
			for client, v := range clients {
				fmt.Println("start sending msg to:", v)
				err := client.WriteMessage(websocket.TextMessage, msgByte)
				defer client.Close()
				if err != nil {
					fmt.Println("send msg fail:", err)
				}

			}
		}
	}
}

// 接收客户端的消息, 并写入chan
func getMsg() {
	for {
		for client := range clientMsg {
			defer client.Close()
			if client == nil {
				delete(clientMsg, client)
				break
			} else {
				go listenMsg(client)
				delete(clientMsg, client)
			}
		}
	}
}

func listenMsg(client *websocket.Conn) {
	var jsonMsg Msg
	for {
		err := client.ReadJSON(&jsonMsg)
		if err != nil {
			fmt.Fprintf(os.Stderr, "read msg from client: %v\n", err)
		}
		fmt.Println(jsonMsg)
		chMsg <- &jsonMsg
	}
}

func HomeHandler(w http.ResponseWriter, r *http.Request) {
	file, err := ioutil.ReadFile(root + "/ws_server/index.html")
	if err != nil {
		fmt.Println(os.Getwd())
		fmt.Println(err)
	}
	_, err = fmt.Fprintf(w, "%s", file)
	if err != nil {
		fmt.Println(err)
	}
}

func WsHandler(w http.ResponseWriter, r *http.Request) {
	ws, err := upgrade.Upgrade(w, r, nil)
	if err != nil {
		log.Println("upgrade:", err)
		fmt.Fprintf(w, "%s", "update websocket fail")
		return
	}
	ws.PongHandler()
	// clients的length作为ID
	lenClient := len(clients) + 1
	clients[ws] = lenClient
	clientMsg[ws] = lenClient

	fmt.Printf("新用户ID %d\n", lenClient)
	clientId := fmt.Sprintf("%d", lenClient)
	err = ws.WriteMessage(websocket.TextMessage, []byte(clientId))
	if err != nil {
		log.Println(err)
	}
}
